//
// Simple demo of the bb_spi_lcd library
// For AVR, the code assumes that a 160x80 ST7735S is connected
// for the non-AVR demo, a TTGO T-Display (ST7789 240x135) is assumed
//

#include <bb_spi_lcd.h>

uint8_t ucBombMask[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x04,0x21,0x00,0x00,
  0x00,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x00,
  0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x38,0xa8,0x00,
  0x00,0x00,0x00,0x01,0x01,0xc0,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x00,
  0x00,0x00,0x00,0x01,0x00,0x24,0x40,0x00,0x00,0x00,0x00,0x0f,0xe0,0x40,0x20,0x00,
  0x00,0x00,0x00,0x0f,0xe0,0x84,0x10,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,
  0x00,0x00,0x00,0x3f,0xf8,0x04,0x00,0x00,0x00,0x00,0x00,0xff,0xfe,0x00,0x00,0x00,
  0x00,0x00,0x00,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x00,
  0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x03,0xdf,0xff,0x80,0x00,0x00,
  0x00,0x00,0x03,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x03,0xbf,0xff,0x80,0x00,0x00,
  0x00,0x00,0x03,0xbf,0xff,0x80,0x00,0x00,0x00,0x00,0x03,0xbf,0xff,0x80,0x00,0x00,
  0x00,0x00,0x03,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x03,0xdf,0xff,0x80,0x00,0x00,
  0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x01,0xf7,0xff,0x00,0x00,0x00,
  0x00,0x00,0x00,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xfe,0x00,0x00,0x00,
  0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00};

SPILCD lcd;

void setup() {
//int spilcdInit(int iLCDType, int bFlipRGB, int bInvert, int bFlipped, int32_t iSPIFreq, int iCSPin, int iDCPin, int iResetPin, int iLEDPin, int iMISOPin, int iMOSIPin, int iCLKPin);
#ifdef __AVR__
  spilcdInit(&lcd, LCD_ST7735S, 1, 0, 1, F_CPU/2, 10, 8, 9, A0, -1, -1, -1); // Prototype pin numbering
#else
  spilcdInit(&lcd, LCD_ST7789_135, FLAGS_NONE, 40000000, 5, 16, -1, 4, -1, 19, 18); // TTGO T-Display pin numbering, 40Mhz
#endif
   spilcdSetOrientation(&lcd, LCD_ORIENTATION_90);
#ifndef __AVR__
   spilcdAllocBackbuffer(&lcd); // can only allocate a back buffer on systems with enough RAM
#endif
  spilcdFill(&lcd, 0, DRAW_TO_LCD);
}

void loop() {
  // put your main code here, to run repeatedly:
int i, iFG, x, y, r1, r2;
uint32_t iTime;
char szTemp[32];
uint16_t usPal[] = {0xf800, 0x07e0, 0x001f, 0x7ff, 0xf81f, 0xffe0, 0xffff, 0x0000};

#ifdef __AVR__
#define WIDTH 160
#define HEIGHT 80
#else
#define WIDTH 240
#define HEIGHT 135
#endif

static int iLineOffset = 0;
static int iColorOffset = 0;
static int iColorDelta = 1;
static int yLogo = 0;
static int yDelta = 1;
int dx, dy;

x = y = 0;
dx = dy = 1;
i = 0; // frame
#ifndef __AVR__
{
uint16_t r, g, b, usColor1, usColor2;
  i = 1;
    iTime = millis();
    for (x=0; x<WIDTH-1; x+=2)
    {
      spilcdDrawLine(&lcd, x, 0, WIDTH-1-x, HEIGHT-1, usPal[i], DRAW_TO_RAM);
    } // for x
    for (y=0; y<HEIGHT-1; y+=2)
    {
      spilcdDrawLine(&lcd, WIDTH-1, y, 0, HEIGHT-1-y, usPal[i], DRAW_TO_RAM);
    }
    spilcdShowBuffer(&lcd, 0,0,WIDTH,HEIGHT, DRAW_TO_LCD);
    iTime = millis() - iTime;
    spilcdWriteString(&lcd, 0,64, (char *)"Indirect Render", 0xffff, 0x0000, FONT_8x8, DRAW_TO_LCD);
    sprintf(szTemp,"Time = %dms", (int)iTime);
    spilcdWriteString(&lcd, 0, 72, szTemp, 0xffff, 0x0000, FONT_8x8, DRAW_TO_LCD);
    delay(4000);
    
  for (i=0; i<250; i++)
  {
    uint16_t usColor = random(65536);
    x = random(WIDTH);
    y = random(HEIGHT);
    r1 = random(4, WIDTH/2);
    r2 = random(4, WIDTH/2);
    spilcdEllipse(&lcd, x, y, r1, r2, usColor,1, DRAW_TO_LCD);
  }
  delay(4000);
  for (int count=0; count<5000; count++)
  {
      // color offset goes between 0 and 0x20
      // use to transition between 2 starting and 2 ending colors for the gradient
      r = iColorOffset;
      g = 1-((1*iColorOffset)>>5);
      b = 0x1f - iColorOffset;
      usColor1 = (r<<11) | (g<<5) | b; // start
      r = 0x1f - iColorOffset;
      g = 0x32 - (((0x17)*iColorOffset)>>5);
      b = iColorOffset;
      usColor2 = (r<<11) | (g<<5) | b; // end
      iColorOffset += iColorDelta; // increase green
      if (iColorOffset < 0)
         {
         iColorOffset = 0;
         iColorDelta = -iColorDelta;
         }
      if (iColorOffset >= 0x1f)
         {
         iColorOffset = 0x1f;
         iColorDelta = -iColorDelta;
         }
      yLogo += yDelta;
      if (yLogo == 0 || yLogo == 155)
         yDelta = -yDelta;

    spilcdRectangle(&lcd, 0, 0, WIDTH, HEIGHT, usColor1, usColor2, 1, DRAW_TO_RAM);
    spilcdWriteString(&lcd, x,y,(char *)"bb_spi_lcd Library", 0xffff,-1,FONT_8x8, DRAW_TO_RAM);
    spilcdWriteString(&lcd, x,y+8,(char *)"by Larry Bank", 0xffff,-1,FONT_8x8, DRAW_TO_RAM);
    {
      int j;
      uint8_t u8Temp[8*40]; // holds the rotated mask
      spilcdRotateBitmap((uint8_t *)ucBombMask, u8Temp, 1, 40, 40, 8, 20, 20, i % 360);
      j = i % 120;
      spilcdDrawPattern(&lcd, u8Temp, 8, j,0,40,40,0x6ff,16);
      spilcdDrawPattern(&lcd, u8Temp, 8, 120-j,0,40,40,0xf81f,16);
      spilcdDrawPattern(&lcd, u8Temp, 8, j,90,40,40,0x6e0,16);
      spilcdDrawPattern(&lcd, u8Temp, 8, 120-j,90,40,40,0x6ff,16);
    }

    spilcdShowBuffer(&lcd, 0,0,WIDTH,HEIGHT, DRAW_TO_LCD);
    x += dx; y += dy;
    if (x == 0) dx = -dx;
    else if (x >= WIDTH-145) dx = -dx;
    if (y == 0) dy = -dy;
    else if (y >= HEIGHT-17) dy = -dy;
    i++;
  } // for count
}
#else
i = 0;
  {
    iTime = millis();
    for (x=0; x<WIDTH-1; x+=2)
    {
      spilcdDrawLine(&lcd, x, 0, WIDTH-1-x, HEIGHT-1, usPal[i], DRAW_TO_LCD);
    } // for x
    for (y=0; y<HEIGHT-1; y+=2)
    {
      spilcdDrawLine(&lcd, WIDTH-1, y, 0, HEIGHT-1-y, usPal[i], DRAW_TO_LCD);
    }
    iTime = millis() - iTime;
    spilcdWriteString(&lcd, 0,64, (char *)"Direct Render", 0xffff, 0x0000, FONT_8x8, DRAW_TO_LCD);
    sprintf(szTemp,"Time = %dms", (int)iTime);
    spilcdWriteString(&lcd, 0, 72, szTemp, 0xffff, 0x0000, FONT_8x8, DRAW_TO_LCD);
    delay(4000);
  } // for i
#endif
    
} // loop
